package com.expert.miniapp.controller;

import com.expert.miniapp.dao.Recommendation;
import com.expert.miniapp.dto.AnalysisReportDTO;
import com.expert.miniapp.dto.RecommendationItemDetailDTO;
import com.expert.miniapp.dto.RecommendationResponseDTO;
import com.expert.miniapp.dto.RecommendationResponseDTO;
import com.expert.miniapp.dto.RecommendationItemSummaryDTO;
import com.expert.miniapp.dto.ResultDTO;
import com.expert.miniapp.service.RecommendationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 聚合推荐控制器
 * 提供基于权重的混合资源推荐API接口
 * 
 * @author System
 * @since 2024
 */
@RestController
@RequestMapping("/")
@CrossOrigin(origins = "*")
public class RecommendationController {

    private static final Logger logger = LoggerFactory.getLogger(RecommendationController.class);

    @Autowired
    private RecommendationService recommendationService;

    @Autowired
    private com.expert.miniapp.service.AnalysisReportService analysisReportService;

    @Autowired
    private com.expert.miniapp.service.DemandService demandService;
    
    /**
     * 测试接口
     */
    @GetMapping(value = "/test", produces = "application/json;charset=UTF-8")
    public ResultDTO<String> test() {
        return ResultDTO.success("Hello World");
    }
    
    /**
     * 获取聚合推荐内容
     * 根据指定数量从各类资源中按权重随机推荐内容
     * 
     * @param expertCount 推荐的科研专家数量，默认为2
     * @param achievementCount 推荐的科技成果数量，默认为2
     * @param instrumentCount 推荐的仪器设备数量，默认为2
     * @param laboratoryCount 推荐的实验室数量，默认为2
     * @param otherResourceCount 推荐的其他资源数量，默认为2
     * @return 包含各类推荐资源的统一响应结构
     */
    @GetMapping(value = "/recommendations", produces = "application/json;charset=UTF-8")
    public ResultDTO<Map<String, Object>> getRecommendations(
            @RequestParam(value = "expertCount", defaultValue = "2") int expertCount,
            @RequestParam(value = "achievementCount", defaultValue = "2") int achievementCount,
            @RequestParam(value = "instrumentCount", defaultValue = "2") int instrumentCount,
            @RequestParam(value = "laboratoryCount", defaultValue = "2") int laboratoryCount,
            @RequestParam(value = "otherResourceCount", defaultValue = "2") int otherResourceCount
    ) {
        try {
            // 参数校验
            if (expertCount < 0 || achievementCount < 0 || instrumentCount < 0 || 
                laboratoryCount < 0 || otherResourceCount < 0) {
                return ResultDTO.error("推荐数量不能为负数");
            }
            
            // 调用服务层获取推荐数据
            Map<String, Object> recommendations = recommendationService.getHomepageRecommendations(
                expertCount, achievementCount, instrumentCount, laboratoryCount, otherResourceCount
            );
            
            return ResultDTO.success(recommendations);
            
        } catch (Exception e) {
            return ResultDTO.error("获取推荐内容失败：" + e.getMessage());
        }
    }

    /**
     * 查询推荐详情
     * 根据推荐ID查询推荐记录及其所有明细
     *
     * @param recommendationId 推荐ID
     * @return 推荐详情DTO
     */
    @GetMapping(value = "/api/recommendations/{recommendationId}", produces = "application/json;charset=UTF-8")
    public ResultDTO<RecommendationResponseDTO> getRecommendationDetail(@PathVariable String recommendationId) {
        logger.info("接收到查询推荐详情请求: recommendationId={}", recommendationId);

        try {
            RecommendationResponseDTO result = recommendationService.getRecommendationDetail(recommendationId);
            logger.info("查询推荐详情成功: totalCount={}", result.getTotalCount());
            return ResultDTO.success(result);

        } catch (IllegalArgumentException e) {
            logger.error("查询推荐详情失败: {}", e.getMessage());
            return ResultDTO.error(e.getMessage());

        } catch (Exception e) {
            logger.error("查询推荐详情失败", e);
            return ResultDTO.error("查询推荐详情失败: " + e.getMessage());
        }
    }

    /**
     * 查询需求的所有推荐记录
     * 根据需求ID查询所有相关的推荐记录列表
     *
     * @param demandId 需求ID
     * @return 推荐记录列表
     */
    @GetMapping(value = "/api/demands/{demandId}/recommendations", produces = "application/json;charset=UTF-8")
    public ResultDTO<List<Recommendation>> getRecommendationsByDemandId(@PathVariable String demandId) {
        logger.info("接收到查询需求推荐记录请求: demandId={}", demandId);

        try {
            List<Recommendation> recommendations = recommendationService.getRecommendationsByDemandId(demandId);
            logger.info("查询成功，找到 {} 条推荐记录", recommendations.size());
            return ResultDTO.success(recommendations);

        } catch (Exception e) {
            logger.error("查询需求推荐记录失败", e);
            return ResultDTO.error("查询需求推荐记录失败: " + e.getMessage());
        }
    }

    /**
     * 生成AI匹配分析报告
     * 根据推荐项ID生成详细的资源与需求匹配分析报告
     *
     * @param requestBody 请求体，包含itemId
     * @return AI生成的分析报告
     */
    @GetMapping(value = "/api/recommendation-items/{itemId}", produces = "application/json;charset=UTF-8")
    public ResultDTO<RecommendationItemSummaryDTO> getRecommendationItemSummary(@PathVariable String itemId) {
        logger.info("收到获取推荐条目基本信息请求: itemId={}", itemId);

        if (itemId == null || itemId.trim().isEmpty()) {
            logger.warn("推荐条目ID为空");
            return ResultDTO.error("推荐条目ID不能为空");
        }

        try {
            RecommendationItemSummaryDTO dto = RecommendationItemSummaryDTO.fromEntity(
                    recommendationService.getRecommendationItemById(itemId)
            );
            return ResultDTO.success(dto);
        } catch (IllegalArgumentException e) {
            logger.error("获取推荐条目失败: {}", e.getMessage());
            return ResultDTO.error(e.getMessage());
        } catch (Exception e) {
            logger.error("获取推荐条目失败", e);
            return ResultDTO.error("获取推荐条目失败: " + e.getMessage());
        }
    }

    @GetMapping(value = "/api/recommendation-items/{itemId}/analysis-report", produces = "application/json;charset=UTF-8")
    public ResultDTO<AnalysisReportDTO> getRecommendationItemAnalysisReport(@PathVariable String itemId) {
        logger.info("收到获取分析报告请求: itemId={}", itemId);

        if (itemId == null || itemId.trim().isEmpty()) {
            logger.warn("推荐条目ID为空");
            return ResultDTO.error("推荐条目ID不能为空");
        }

        try {
            AnalysisReportDTO report = analysisReportService.getAnalysisReport(itemId);
            return ResultDTO.success(report);
        } catch (IllegalArgumentException | IllegalStateException e) {
            logger.error("获取分析报告失败: {}", e.getMessage());
            return ResultDTO.error(e.getMessage());
        } catch (Exception e) {
            logger.error("获取分析报告失败", e);
            return ResultDTO.error("获取分析报告失败: " + e.getMessage());
        }
    }

    /**
     * 获取推荐项详细信息（包含用户和需求信息）
     *
     * @param itemId 推荐项ID
     * @return 推荐项详细信息DTO
     */
    @GetMapping(value = "/api/recommendation-items/{itemId}/detail", produces = "application/json;charset=UTF-8")
    public ResultDTO<RecommendationItemDetailDTO> getRecommendationItemDetail(@PathVariable String itemId) {
        logger.info("接收到获取推荐项详细信息请求: itemId={}", itemId);

        if (itemId == null || itemId.trim().isEmpty()) {
            logger.warn("推荐项ID为空");
            return ResultDTO.error("推荐项ID不能为空");
        }

        try {
            RecommendationItemDetailDTO detail = recommendationService.getRecommendationItemDetail(itemId);
            logger.info("获取推荐项详细信息成功: itemId={}", itemId);
            return ResultDTO.success(detail);
        } catch (IllegalArgumentException e) {
            logger.error("获取推荐项详细信息失败: {}", e.getMessage());
            return ResultDTO.error(e.getMessage());
        } catch (Exception e) {
            logger.error("获取推荐项详细信息失败", e);
            return ResultDTO.error("获取推荐项详细信息失败: " + e.getMessage());
        }
    }

    @PostMapping(value = "/api/recommendation/analysis", produces = "application/json;charset=UTF-8")
    public ResultDTO<com.expert.miniapp.dto.AnalysisReportDTO> generateAnalysisReport(
            @RequestBody Map<String, String> requestBody
    ) {
        String itemId = requestBody.get("itemId");

        logger.info("接收到生成分析报告请求: itemId={}", itemId);

        if (itemId == null || itemId.trim().isEmpty()) {
            return ResultDTO.error("推荐项ID不能为空");
        }

        try {
            com.expert.miniapp.dto.AnalysisReportDTO result = analysisReportService.generateAnalysisReport(itemId);
            logger.info("分析报告生成成功: itemId={}, reportLength={}",
                    itemId,
                    result.getAnalysisReport() != null ? result.getAnalysisReport().length() : 0);
            return ResultDTO.success(result);

        } catch (IllegalArgumentException e) {
            logger.error("生成分析报告失败: {}", e.getMessage());
            return ResultDTO.error(e.getMessage());

        } catch (Exception e) {
            logger.error("生成分析报告失败", e);
            return ResultDTO.error("生成分析报告失败: " + e.getMessage());
        }
    }

    /**
     * 基于需求ID进行AI智能匹配，并将推荐记录与明细写入数据库。
     */
    @PostMapping(value = "/api/recommendations/match", produces = "application/json;charset=UTF-8")
    public ResultDTO<RecommendationResponseDTO> matchRecommendations(@RequestBody Map<String, String> requestBody) {
        String demandId = requestBody.getOrDefault("demandId", "");
        logger.info("接收到AI智能匹配请求: demandId={}", demandId);

        if (demandId == null || demandId.trim().isEmpty()) {
            return ResultDTO.error("需求ID不能为空");
        }

        try {
            RecommendationResponseDTO dto = demandService.runAIMatchAndPersist(demandId);
            logger.info("AI智能匹配完成: recommendationId={}, totalCount={}", dto.getRecommendationId(), dto.getTotalCount());
            return ResultDTO.success(dto);
        } catch (IllegalArgumentException e) {
            logger.error("AI智能匹配失败: {}", e.getMessage());
            return ResultDTO.error(e.getMessage());
        } catch (Exception e) {
            logger.error("AI智能匹配失败", e);
            return ResultDTO.error("AI智能匹配失败: " + e.getMessage());
        }
    }
}



